/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[JSP06.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package _notes.jsp;

/**
 * EL表达式
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public final class JSP06 {

	public void elConcept() {
		/**
		 * EL[Expression Language]<br/>
		 * 
		 * EL主要作用<br/>
		 * 1. 获取数据: EL可以访问某个Web作用域中的对象, 访问JavaBean的属性, 访问list, Map集合, 访问数组 <br/>
		 * 2. 执行运算: EL可以在JSP页面中执行一些基本的关系运算, 逻辑运算和算术运算<br/>
		 * 3. 隐式对象: EL定义了一些隐式对象, 利用它们可以获得对JSP内置对象的引用, 从而获得这些对象中的数据 <br/>
		 * 4. EL函数: EL表达式允许自定义EL函数, 以在JSP页面中通过EL表达式调用Java类的方法<br/>
		 */
	}

	public void elGrammar() {
		/**
		 * EL表达式语法<br/>
		 * 
		 * <code>
		 * ${sessionScope.customer.name} // 等价于下一行
		 * ${sessionScope.customer["name"]}
		 * 
		 * ${sessionScope.customers[0].name} // 得到第一个Customer的name
		 * </code><br/>
		 * 
		 * 什么时候使用[]<br/>
		 * 1. 当要存取的属性名称包含一些特殊字符, 如 . 或 - <br/>
		 * <code>
		 * ${sessionScope.customer[cust-name]} // 包含有: -
		 * ${sessionSope[bean.Customer].name} // 包含有: 包名 bean.Customer
		 * </code><br/>
		 * 2. 动态取值<br/>
		 * <code>
		 * ${sessionScope.customer[property]} // 这里的prop可以是name, 可以是ID
		 * </code>
		 * 
		 * ${username}: 它的意思是取出某一范围中名称为username的变量,
		 * 调用pageContext.findAttribute()方法, 依序到page, request, session,
		 * application范围内查找, 假如途中找到username就直接回传, 不再继续找下去, 但是假如全部的范围都没有找到时,
		 * 就回传null<br/>
		 */

		/**
		 * EL表达式的规则<br/>
		 * 
		 * ${express1[express2]}<br/>
		 * 1. 当expression1为null时, 得到null<br/>
		 * 
		 * 2. 当expression2为null时, 得到null<br/>
		 * 
		 * 3. 当expression1为Map类型时, expression1代表Map, expression2代表Map的key<br/>
		 * a. 如果Map不包含这个key, 则返回null<br/>
		 * b. 否则调用map.get(key)方法得到值<br/>
		 * 
		 * 4. 当expression1为List或者数组类型时, expression2表示了索引, 为int类型<br/>
		 * a. 如果expression2不能转换为int类型时会产生error<br/>
		 * b. 如果产生ArrayIndexOutOfBoundsException/IndexOutOfBoundsException,
		 * 得到null <br/>
		 * c. 如果产生其他异常, 则会产生error<br/>
		 * d. 如果没有任何error,
		 * 则返回expression1[expression2]或expression1.get(expression2)的结果<br/>
		 * 
		 * 5. 如果expression1为JavaBean对象时, expression2表示该对象的属性<br/>
		 * a. 如果调用该JavaBean的getter方法产生异常, 则会产生error<br/>
		 * b. 如果没有error, 返回getter方法的结果<br/>
		 * 
		 * EL自动类型转换<br/>
		 * <code>
		 * ${param.count + 20} // 如果count=10, 结果为30, EL将请求参数的字符串转换为了数字
		 * </code><br/>
		 * 
		 * 类型转换规则<br/>
		 * // TODO
		 */
	}

	public void elImplicitObjects() {
		/**
		 * EL的隐含对象[11个]<br/>
		 * 
		 * 1. 范围有关的隐含对象<br/>
		 * pageScope; 取得page范围内属性名称对应的属性值<br/>
		 * requestScope; 取得request范围内属性名称对应的属性值<br/>
		 * sessionScope; 取得session范围内属性名称对应的属性值<br/>
		 * applicationScope; 取得application范围内属性名称对应的属性值<br/>
		 * 以上四个隐含对象只能用来取得属性范围的值<br/>
		 * 
		 * 2. 请求参数有关的隐含对象<br/>
		 * param; 相当于request.getParameter(String name)<br/>
		 * paramValues; 相当于request.getParameterValues(String name)<br/>
		 * 
		 * 3. 其他隐含对象<br/>
		 * header; 相当于request.getHeader(String name)<br/>
		 * headerValues; 相当于request.getHeaders(String name)<br/>
		 * <code>
		 * ${header["User-Agent"]}
		 * </code>
		 * 
		 * cookie; 相当于request.getCookies()<br/>
		 * <code>
		 * ${cookie.JSESSIONID.name}
		 * ${cookie.JSESSIONID.value}
		 * </code><br/>
		 * 
		 * initParam; 相当于application.getInitParameter(String name)<br/>
		 * 
		 * pageContext; 表示此JSP的pageContext<br/>
		 * ${pageContext}可以用来获得其他的JSP隐含对象<br/>
		 * <code>
		 * ${pageContext.request.queryString} // 取得请求的参数字符串
		 * ${pageContext.request.requestURL} // 取得请求的 URL, 但不包括请求之参数字符串
		 * ${pageContext.request.contextPath} // webApp的名称
		 * ${pageContext.request.method} // 取得HTTP的方法[GET/POST]
		 * ${pageContext.request.protocol} // 取得使用的协议[HTTP/1.1 HTTP/1.0]
		 * ${pageContext.request.remoteUser} // 取得用户名称
		 * ${pageContext.request.remoteAddr} // 取得用户的IP地址
		 * ${pageContext.session.new} // 判断session是否为新的
		 * ${pageContext.session.id} // 取得session的 ID
		 * ${pageContext.servletContext.serverInfo} // 取得主机端的服务信息
		 * </code>
		 */
	}

	public void elReservedWords() {
		/**
		 * EL的保留字<br/>
		 * 
		 * and/or<br/>
		 * eq/gt/ge/lt/le/ne<br/>
		 * true/false<br/>
		 * no/null/empty<br/>
		 * div/mod<br/>
		 * instanceof<br/>
		 */
	}

	public void elOperators() {
		/**
		 * EL算数运算符<br/>
		 * + ${10 + 10}<br/>
		 * - ${10 - 10}<br/>
		 * * ${10 * 10}<br/>
		 * / ${10 / 10}或${10 div 10}<br/>
		 * % ${10 % 10}或${10 mod 10}<br/>
		 * 
		 * EL关系运算符 <br/>
		 * ==/eq ${10 == 10}或${10 eq 10}<br/>
		 * !=/ne ${10 != 10}或${10 ne 10}<br/>
		 * </lt ${10 < 10}或${10 lt 10}<br/>
		 * >/gt ${10 > 10}或${10 gt 10}<br/>
		 * <=/le ${10 <= 10}或${10 le 10}<br/>
		 * >=/ge ${10 >= 10}或${10 ge 10}<br/>
		 * 
		 * EL逻辑运算符<br/>
		 * &&/and ${A && B}或${A and B}<br/>
		 * ||/or ${A || B}或${A or B}<br/>
		 * !/not ${!A}或${not A}<br/>
		 * 
		 * 其他运算符<br/>
		 * empty运算符<br/>
		 * ${empty param.name}可以判断param.name是否为null<br/>
		 * 其还可以判断String是否为空串, 集合数组是否没有任何元素<br/>
		 * 
		 * 条件运算符<br/>
		 * ${A ? B : C}<br/>
		 * 
		 * 括号运算符<br/>
		 * 用来改变执行优先级<br/>
		 */
	}

	public void elFunctions() {
		/**
		 * EL函数<br/>
		 * <code>
		 * <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
		 * </code><br/>
		 * 
		 * 常用函数<br/>
		 * fn:contanis(str, subStr); 如果str中包含subStr返回true<br/>
		 * fn:containsIngoreCase(str, subStr); 同上但忽略大小写<br/>
		 * fn:endswith(str, suffix); 如果str以suffix结尾返回true<br/>
		 * fn:escapeXml(str); 将有特殊意义的XML/HTML转换为对应的XML Character Entity Code并返回
		 * <br/>
		 * fn:indexOf(str, subStr); 返回subStr在str中第一次出现的位置<br/>
		 * fn:join(array, separator); 将给定的数组使用指定的间隔符串在一起, 组成一个新的字符串并返回<br/>
		 * fn:length(item); 返回数组的length, 集合的size(), String的length()<br/>
		 * fn:replace(str, before, after); 返回一个String,
		 * 用after字符串替换str所有出现before字符串的地方, 并返回替换后的结果<br/>
		 * fn:split(str, separator);使 用指定分隔符分割str, 返回一个数组<br/>
		 * fn:startsWith(str, prefix); 如果str以指定的prefix开头, 返回true<br/>
		 * fn:substring(str, begin, end); 截取子串, [begin, end]<br/>
		 * fn:substringAfter(str, subStr); 返回subStr在str中后面的那一部分字符串<br/>
		 * fn:substringBefore(str, subStr); 返回subStr在str中前面的那一部分字符串<br/>
		 * fn:toLowerCase(str); 将str所有字符转换为小写并返回<br/>
		 * fn:toUpperCase(str); 将str所有字符转换为大写并返回<br/>
		 * fn:trim(str); 去除str首尾的空格并返回<br/>
		 */
	}

	public void selfDefinedFunction() {
		/**
		 * EL自定义函数: 在EL表达式中调用的某个Java类的静态方法, 这个静态方法需在web应用程序中进行配置才可以被EL表达式调用<br/>
		 * EL自定义函数可以扩展EL表达式的功能, 让EL表达式完成普通Java程序代码所能完成的功能<br/>
		 * 
		 * 定义函数<br/>
		 * <code>
		 * public static String concat(String str1, String str2) {
		 *     return str1 + str2;
		 * }
		 * </code><br/>
		 * 
		 * 将函数配置到tld文件中<br/>
		 * <code>
		 * <function>
		 *     <name>concat</name>
		 *     <function-class>jsp.el.MyELFunction</function-class>
		 *     <function-signature>java.lang.String concat(java.lang.String, java.lang.String)</function-signature>
		 * </function>
		 * </code>
		 */
	}
}
